package device;

import base.UsersBaseInterface;
import device.callbacks.VerifyOnce;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Collection;
import java.util.HashMap;

// 用户终端
public class Terminal extends Device {
    private static final Logger logger = LoggerFactory.getLogger(Terminal.class);
    public Terminal(SocketChannel socketChannel, UsersBaseInterface users) {
        super(socketChannel, users);
    }

    @Override
    public void subscribe(Device targetDevice) {
        if (targetDevice != null) {
            targetDevice.addSubscriber(this);
            // 将充电桩设备设置为手机指令的订阅者
            this.addSubscriber(targetDevice);

            // 向充电桩发送当前用户的余额信息

        } else {
            System.out.println("Error: 无法订阅，目标设备为空！");
        }
    }

    @Override
    public boolean subscribe(Device targetDevice, VerifyOnce verify) {
        String userName = verify.verifyOnce();
        if (userName == null) {
            try {
                simpleSend("用户名与密码验证失败！");
            } catch (IOException _) {
            }
            return false;
        }
        // 充电桩和手机设备都绑定该用户名
        targetDevice.bundleUserName(userName);
        bundleUserName(userName);
        // 相互订阅
        subscribe(targetDevice);
        // 向充电桩发送余额信息
        float balance = users.queryUserBalance(userName);
        try {
            if (balance >= 0.0) {
                targetDevice.simpleSend("g=%s,a=%.2f".formatted(
                        userName, balance));
            }
        } catch (IOException e) {
            logger.error("向充电桩发送余额信息时，抛出异常。");
        }
        return true;
    }

    @Override
    public void update(HashMap<String, String> msgsSet) {
        Collection<String> keySet = msgsSet.keySet();
        for (String key : keySet) {
            String msgValue = msgsSet.get(key);
            if (msgValue != null) {
                String value = keys.get(key);
                if (value != null && !msgValue.equals(value)) {
                    /* 不会插入新键 */
                    keys.replace(key, msgValue);
                    updateFlag = true;
                }
            }
        }

        /* 存在 b= 字段，充值 */
        String balance = msgsSet.get("b");
        if (balance != null) {
            try {
                float value = Float.parseFloat(balance);
                users.updateUserBalance(userNameBundle, value, false);
                /* 获取充值以后的当前值 */
                value = users.queryUserBalance(userNameBundle);
                if (value >= 0) {
                    msgsSet.replace("b", Float.toString(value));
                }
            } catch (NumberFormatException _) {
            }
        }
    }

    @Override
    public void publish(Collection<String> collects) throws IOException {
        if (!updateFlag) {
            return;
        }

        StringBuilder buffer = new StringBuilder();

        //buffer.append("devID=").append(deviceID);

        boolean flag = false;
        for (String key : collects) {
            if (flag) {
                buffer.append(",");
            }
            String value = keys.get(key);
            if (value != null) {
                buffer.append(key).append("=").append(keys.get(key));
            } else {
                continue;
            }
            flag = true;
        }

        // 发给单片机设备的消息需要加上 \r\n
        buffer.append("\r\n");

        // 将消息转发给订阅者
        for (Device dev : subscribeSet) {
            ByteBuffer message = ByteBuffer.wrap(buffer.toString().getBytes());
            dev.sendBuffer(message);
            updateFlag = false;
        }
    }
}
